package io.nads.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import dev.langchain4j.data.message.*;
import io.nads.config.RabbitConfig;
import io.nads.constant.RedisConstant;
import io.nads.context.BaseContext;
import io.nads.dto.ChatMessageDTO;
import io.nads.dto.Result;
import io.nads.entity.ChatSession;
import io.nads.entity.UserChatMessage;
import io.nads.mapper.ChatMessageMapper;
import io.nads.mapper.ChatSessionMapper;
import io.nads.mapper.ChatSessionServiceImpl;
import io.nads.utils.MessageIdWorker;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static io.nads.constant.ChatMessageType.*;
import static io.nads.constant.RedisConstant.CHAT_SESSION_TOPIC_KEY_PREFIX;

/**
 * @Author: shzhu
 * @Date: 2025/9/23 23:16
 * @Description:
 */
@Service
@Data
@Slf4j
public class ChatService {
    private List<UserChatMessage> historyMessage;

    @Autowired
    private ChatMessageMapper chatMessageMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private QWenService qWenService;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RabbitProperties rabbitProperties;


    public ChatService() {
        this.historyMessage = new LinkedList<>();
    }

    /**
     * 发送消息
     *
     * @param message
     */
    public void sendMessage(UserChatMessage message) {
        rabbitTemplate.convertAndSend(
                RabbitConfig.EXCHANGE_NAME,
                RabbitConfig.ROUTING_KEY,
                message
        );
    }

    private List<ChatMessage> userMsg2ChatMsg(List<UserChatMessage> messages) {
        return messages.stream()
                .map(this::convertToChatMessage)
                .toList();
    }

//    private List<UserChatMessage> chatMsg2UserChatMsg(List<ChatMessage> messages) {
//        messages.stream().map()
//
//    }
//
//    private UserChatMessage convertToUserChatMsg(ChatMessage message) {
//        UserChatMessage userChatMessage = new UserChatMessage();
//
//    }


    /**
     * 查询出历史纪录
     */
    public List<UserChatMessage> loadHistoryMessages() {
        Long userId = BaseContext.getCurrentId();
        Long currentSessionId = BaseContext.getCurrentSessionId();

        if (userId == null || currentSessionId == null)
            throw new RuntimeException("用户或者会话不存在");

        // 查询缓存
        String key = "chat:" + userId + ":" + currentSessionId + ":";
//        List<UserChatMessage> list = redisTemplate.opsForList().range(key, 0, -1);
        List<Object> rawList = redisTemplate.opsForList().range(key, 0, -1);

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        List<UserChatMessage> list = rawList.stream()
                .map(o -> mapper.convertValue(o, UserChatMessage.class))
                .collect(Collectors.toList());

        if (list != null && !list.isEmpty()) {
            this.historyMessage = list;
            return list;
        }

        // 查询数据库
        // 查询出所有的历史会话，类型为UserChatMessage
        QueryWrapper<UserChatMessage> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "message_type", "content", "message_type", "created_time")
                .eq("user_id", userId)
                .eq("session_id", currentSessionId);


        list = chatMessageMapper.selectList(queryWrapper);

        // 转换为langchain4j的消息,保存到列表中
        //        this.historyMessage = messages.stream()
        //                .map(this::convertToChatMessage)
        //                .collect(java.util.stream.Collectors.toList());


        // 写入缓存
        if (!list.isEmpty()) {
            redisTemplate.opsForList().rightPushAll(key, list);
            // 设置过期时间，例如1小时
            redisTemplate.expire(key, 3600, TimeUnit.SECONDS);
        }
        return list;
    }

    /**
     * 转化消息类型，风转为langchain4j的消息类型
     *
     * @param msg
     * @return
     */
    private ChatMessage convertToChatMessage(UserChatMessage msg) {
        switch (msg.getMessageType()) {
            case USER:
                return UserMessage.from(msg.getContent());
            case AI:
                return AiMessage.from(msg.getContent());
            case SYSTEM:
                return SystemMessage.from(msg.getContent());
            default:
                return UserMessage.from("");
        }
    }


    /**
     * 聊天类
     *
     * @param userMessage
     * @return
     */
    public UserChatMessage chat(String userMessage) throws Exception {

        // 获得历史消息纪录
        Long userId = BaseContext.getCurrentId();
        Long sessionId = BaseContext.getCurrentSessionId();
        if (userId == null || "".equals(userId) || sessionId == null || "".equals(sessionId)) {
            log.error("userId 或者 sessionId 为空");
            throw new Exception("userId 或者 sessionId 为空");
        }
        String key = "chat:" + userId + ":" + sessionId + ":";
        historyMessage = loadHistoryMessages();

        // 将用户消息发送到消息队列，便于持久化
        // 插入用户消息

        // 封装成自定义的消息类
        UserChatMessage userChatMsg = new UserChatMessage(MessageIdWorker.generateId(), sessionId, userId, USER, userMessage, LocalDateTime.now());
        historyMessage.add(userChatMsg);
        redisTemplate.opsForList().rightPush(key, userChatMsg);
        sendMessage(userChatMsg);

        // 将当前的用户消息历史记录封装成LangChain4J的消息列表
        List<ChatMessage> chatMessagesHistory = userMsg2ChatMsg(historyMessage);


        // 获得AI消息
        //todo
//        String topic = (String) redisTemplate.opsForValue().get(CHAT_SESSION_TOPIC_KEY_PREFIX);
        String topicKey = RedisConstant.CHAT_SESSION_TOPIC_KEY_PREFIX + userId;
        String topic = stringRedisTemplate.opsForValue().get(topicKey);
        log.info("从redis中获取到了 topic {}", topic);
//        topic = "幽默的秦始皇";
        String prompt = "假设你是" + topic + ",你的所有回答使用" + topic + "的风格回答，另外，你给我的回答中，不要携带任何的语气词，我仅仅只需要回复的内容";
        String aiResponse = qWenService.chatWithSystem(prompt, chatMessagesHistory);

        UserChatMessage userChatMessageAiRes = new UserChatMessage(MessageIdWorker.generateId(), sessionId, userId, AI, aiResponse, LocalDateTime.now());

        // redis中保存这一轮用户消息和AI消息
        redisTemplate.opsForList().rightPush(key, userChatMessageAiRes);
        historyMessage.add(userChatMessageAiRes);
        sendMessage(userChatMessageAiRes);
        return userChatMessageAiRes;
    }

    public List<ChatMessageDTO> openSession() {
        return null;
    }


    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    ChatSessionMapper chatSessionMapper;

    @Autowired
    ChatSessionServiceImpl chatSessionServiceImpl;

    public Result getAllChatMessagesAndSwitch(Long chatSessionId) {
        if (chatSessionId == null) {
            return Result.fail("请先创建会话哦");
        }
        chatSessionServiceImpl.switchSessionContext(chatSessionId);
        List<UserChatMessage> historyMessage = loadHistoryMessages();
        log.info("historyMessage={}", historyMessage);
        if (historyMessage == null) {
            return Result.fail("当前会话初始失败");
        }
        return Result.ok(historyMessage);
    }
}
